package eclipse.lib.graphics;
import javax.media.opengl.*;
import eclipse.Constants;
import eclipse.client.*;
import eclipse.lib.graphics.shaders.GLColor;
import eclipse.util.*;
/**
 * The GLObject class represents the OpenGL Object and handles all of the OpenGL calls
 */
public class GLRenderer implements GLEventListener
{	
	public static int fps = 0;
	public void display(GLAutoDrawable drawable) 
	{			
		GL gl = drawable.getGL();	
		fps ++;
		gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);  
		if(Database.MENUSTATE == eclipse.Constants.MENUSTATE_SPLASHSCREEN)
		{
			drawSplashScreen(gl);		
			Database.particlePack.reposition(gl);
		}
		else if(Database.MENUSTATE == eclipse.Constants.MENUSTATE_INGAME)
		{				
			gl.glPushMatrix();
			{		
				if(Database.RENDER_AS_3D)
				{					
					gl.glRotatef(-45f, 1f, 0f, 0f);
					gl.glTranslatef(Database.CameraX, Database.CameraY + 0.5f, 0.5f);
					GLPrimitives.drawLayer(gl, 5);	
					gl.glRotatef(45f, 1f, 0f, 0f);
					GLPrimitives.drawSkybox(gl, Database.tSkyBox);
				}		
				else
				{					
					gl.glTranslatef(Database.CameraX, Database.CameraY, 0f);
					GLPrimitives.drawLayer(gl, 5);
					GameLogic.drawPlayers(gl);					
				}						
			}			
			gl.glPopMatrix();	
		}
		else if(Database.MENUSTATE == Constants.MENUSTATE_CHARSELECT)
			drawCharSelect(gl);
		Database.fpsCount++;
	}	
	private static void drawCharSelect(GL gl)
	{
		gl.glPushMatrix();
			GLPrimitives.drawPlasmaFilter(gl, Constants.SCREENFILTER, Constants.SPLASHFILTER, Database.tBLANK, Database.logoSpin);			
		gl.glPopMatrix();
		Database.logoSpin += 1f;
	}
	private static void drawSplashScreen(GL gl)
	{
		gl.glPushMatrix();
		{
			GLPrimitives.drawPlasmaFilter(gl, Constants.SCREENFILTER, Constants.SPLASHFILTER, Database.tBLANK, Database.logoSpin);
			gl.glTranslatef(320f, 240f, -128f);		
			gl.glPushMatrix();
			{
				gl.glRotatef(Database.logoSpin, 1f, 0f, 0f);
				gl.glCallList(Database.ID_LOGO);
			}
			gl.glPopMatrix();
			
			gl.glPushMatrix();
			{
				gl.glRotatef(Database.logoSpin * 1.1f, -1f, 0f, 0f);
				gl.glCallList(Database.ID_LOGO);
			}
			gl.glPopMatrix();
			
			gl.glPushMatrix();
			{
				gl.glRotatef(Database.logoSpin * 1.2f, 0f, 1f, 0f);
				gl.glCallList(Database.ID_LOGO);
			}
			gl.glPopMatrix();
			
			gl.glPushMatrix();
			{				
				gl.glRotatef(Database.logoSpin * 1.3f, 0f, -1f, 0f);
				gl.glCallList(Database.ID_LOGO);
			}
			gl.glPopMatrix();
			
			gl.glPushMatrix();
			{
				gl.glRotatef(Database.logoSpin * 1.4f, 1f, 1f, 0f);
				gl.glCallList(Database.ID_LOGO);
			}
			gl.glPopMatrix();
			
			gl.glPushMatrix();
			{
		
				gl.glRotatef(Database.logoSpin * 1.5f, -1f, 1f, 0f);
				gl.glCallList(Database.ID_LOGO);
			}
			gl.glPopMatrix();
			
			gl.glPushMatrix();
			{
				gl.glRotatef(Database.logoSpin * 1.6f, 1f, -1f, 0f);
				gl.glCallList(Database.ID_LOGO);
			}
			gl.glPopMatrix();
			
			gl.glPushMatrix();
			{
				gl.glRotatef(Database.logoSpin * 1.7f, -1f, -1f, 0f);
				gl.glCallList(Database.ID_LOGO);								 		
			}
			gl.glPopMatrix();
		}
		gl.glPopMatrix();			
			
		Database.logoSpin += 1f;	
	}
	public void displayChanged(GLAutoDrawable GLDraw, 
			boolean modeChanged, boolean deviceChanged) 
	{
		
	}
	public void init(GLAutoDrawable GLDraw) 
	{		 	
		
		//initialize the GL object
		GL gl = GLDraw.getGL();  
	    if(Database.FPS == 1)
		    gl.setSwapInterval(1);
		gl.glShadeModel(GL.GL_SMOOTH);
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		gl.glClearDepth(1.0f);
		gl.glEnable(GL.GL_DEPTH_TEST);
		gl.glEnable(GL.GL_TEXTURE_2D);
				
		gl.glDepthFunc(GL.GL_LEQUAL);
		if(Database.HIGH_RES)
		{
			gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
			gl.glHint(GL.GL_POLYGON_SMOOTH_HINT, GL.GL_NICEST);
		}
		else
		{
			gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_FASTEST);		
			gl.glHint(GL.GL_POLYGON_SMOOTH_HINT, GL.GL_FASTEST);
		}		
		loadTextures();		
		buildLists(gl);
		System.out.println("OpenGL is Initialized");
				
		new GLColor(1f, 0.1f, 0f);		
		Database.particlePack.generateParticle(
			1000, 200, 2f, 
			new eclipse.lib.Position(GLPrimitives.getX(10), GLPrimitives.getY(0), 0f),
			320, new eclipse.lib.Position(0f, 1f, 0f),
			10, new eclipse.lib.Position(0f,  1f, 0f),
			0, new eclipse.lib.Position(0f,    5f, 0f),
			0, Database.tBLANK, new GLColor(0.1f, 0.1f, 0.1f), true, true);		
		
	}
	/**
	 * Loads the textures used
	 *
	 */
	public static void loadTextures()
	{
		try 
		{					
			System.out.println("loaded standard graphics...");
			Database.tLogo = GLTextureLoader.loadIMG(new ERL("jar://gfx/logo"), Database.HIGH_RES);
			Database.tBLANK = GLTextureLoader.loadIMG(new ERL("jar://gfx/blank"), Database.HIGH_RES);									
			for(int i = 0; i < Database.MAX_SPRITESETS; i++)
				Database.tSpriteSheet[i] = GLTextureLoader.loadIMG(new ERL(Database.SPRITEDATABASE + "sprite" + i), false);
			for(int i = 0; i < Database.MAX_TILESETS; i++)
				Database.tTileSheet[i] = GLTextureLoader.loadIMG(new ERL(Database.TILEDATABASE + "tiles" + i), Database.HIGH_RES);
			Database.tFont = GLTextureLoader.loadIMG(new ERL("jar://gfx/font"), Database.HIGH_RES);
			
		} 
		catch (Exception e) 
		{
			eclipse.ErrorManager.handleError(e);
		}	
	}
	/**
	 * Builds all of the objects used in multiple areas
	 * @param gl OpenGL object
	 */ 
	public static void buildLists(GL gl)
	{
		Database.ID_LOGO = gl.glGenLists(1);
		Database.ID_MENU = gl.glGenLists(1);
		//Logo object
		gl.glNewList(Database.ID_LOGO, GL.GL_COMPILE);
			GLPrimitives.drawQuad(gl, Constants.SPLASHRECT, Database.tLogo);		
		gl.glEndList();				
	}
	public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)
	{
		@SuppressWarnings("unused")
		double left, right, bottom, top, zNear, zFar, fov, aspect;
		fov 	= 45d;
		aspect 	= (double) width / (double) height;
		zNear 	= 0.1d;
		zFar  	= 1000.0d;
					
		top 	= Math.tan(fov* Math.PI /360) * zNear;
		bottom 	= -top;
		left 	= aspect * bottom;
		right 	= aspect * top;
		
		GL gl = drawable.getGL();			
		gl.setSwapInterval(1);
		gl.glViewport(0, 0, width, height);
		gl.glMatrixMode(GL.GL_PROJECTION);
		gl.glLoadIdentity();
//		gl.glFrustum(left, right, bottom, top, zNear, zFar);
		gl.glOrtho(0d, 640d, 480d, 0d, 0d, 1000d);	
		gl.glMatrixMode(GL.GL_MODELVIEW);
		gl.glLoadIdentity();
		
	}
}
